package com.diasuite.client;

import java.util.ArrayList;
import java.util.Iterator;

import com.diasuite.shared.*;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.SourcesTabEvents;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TabBar;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.TabListener;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.event.logical.shared.AttachEvent.Handler;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.ui.SimpleCheckBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.widget.client.TextButton;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Grid;
//import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import java.util.Date;

import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HorizontalPanel;


/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */


public class DiaSuite implements EntryPoint, ValueChangeHandler  {

	public static interface CwConstants extends Constants {
		String cwTabPanelDescription();

		String cwTabPanelName();

		String cwTabPanelTab0();

		String cwTabPanelTab2();

		String[] cwTabPanelTabs();
	}

	/**
	 * An instance of the constants.
	 */

	private CwConstants constants;
	private static final String JSON_URL = GWT.getModuleBaseURL() + "?q=";

	/**
	 * Initialize this example.
	 * 
	 */
	final TabLayoutPanel tabPanel = new TabLayoutPanel(2.5, Unit.EM);
	Label lblWelcome=new Label();
	Label lbl1=new Label();
	Label lbl2=new Label();
	Label lbl3=new Label();
	Label lbl4=new Label();
	FlexTable flexTable_1 = new FlexTable();
	SimplePanel Panel = new SimplePanel();


	Image Ikitchen = new Image(ImageResource.INSTANCE.kitchen());
	Image Ibedroom = new Image(ImageResource.INSTANCE.bedroom());
	Image Ilivingroom = new Image(ImageResource.INSTANCE.livingroom());
	Image Ioutside = new Image(ImageResource.INSTANCE.outside());
	Image Ibathroom = new Image(ImageResource.INSTANCE.bathroom());
	static String drapp1 = new String();
	static String drapp2 = new String();
	static String drapp3 = new String();
	static String drapp4 = new String();
	static String oldToken = new String();
	static JsArray<EquipmentData> listState;

	static final ArrayList <String>Tokens = new ArrayList<String>();
	static JsArray<EquipmentData> listDevices;
	String State = new String();


	private final Button btnAmpoule = new Button("Eclairage");
	private final PushButton btnAccueil = new PushButton("Accueil");
	private final Button btnSecurite = new Button("S&eacute;curit&eacute;");
	private final Button btnMultimedia = new Button("Multim&eacute;dia");
	private final Button btnInformation = new Button("Informations");
	private final Button btnTemperature = new Button("Temp&eacute;rature");
	private final PushButton pshbtnRetour = new PushButton("Retour","Retour");
	private Label errorMsgLabel = new Label();




	public void onModuleLoad() {

		String url = JSON_URL+"getAllDevices";
		url = URL.encode(url);
		System.out.println(url);
		Window.alert(url);
		// Send request to server and catch any errors.
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);

		try {
			Request request = builder.sendRequest(null, new RequestCallback() {
				@Override
				public void onError(Request request, Throwable exception) {
					displayError("Couldn't retrieve JSON");
				}

				public void onResponseReceived(Request request, Response response) {
					if (200 == response.getStatusCode()) {
						//Nothing
					} else {
						displayError("Couldn't retrieve JSON (" + response.getStatusText() + ")");
					}
				}

			});


		} catch (RequestException e) {
			displayError("Couldn't retrieve JSON");
		}






		String initToken = History.getToken();
		if (initToken.length() == 0) {
			History.newItem("home");
			Tokens.add("home");
		}


		// Create a tab panel
		final RootPanel rootPanel = RootPanel.get();
		tabPanel.setAnimationDuration(1000);
		tabPanel.getElement().getStyle().setMarginBottom(10.0, Unit.PX);

		tabPanel.add(flexTable_1, "Par lieux", false);





		Ikitchen.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {

				History.newItem("Kitchen");
			}
		});

		Ibedroom.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				flexTable_1.clear();
				lblWelcome.setText("Nous sommes dans la chambre");
				History.newItem("Bedroom");

			}
		});
		Ilivingroom.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				flexTable_1.clear();
				lblWelcome.setText("Nous sommes dans le salon");
				History.newItem("Salon");

			}
		});

		Ibathroom.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				flexTable_1.clear();
				lblWelcome.setText("Nous sommes dans la salle de bain");
				History.newItem("Bathroom");

			}
		});
		Ioutside.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				flexTable_1.clear();
				lblWelcome.setText("Nous sommes sur la terrasse");
				History.newItem("Outside");

			}
		});


		btnAmpoule.addClickHandler(new ClickHandler() {
			int i = 0;

			public void onClick(ClickEvent event) {

				ChooseRequestLocation(Tokens,"Eclairage");
				History.newItem("Eclairage");
			}
		});

		btnAccueil.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				flexTable_1.clear();
				flexTable_1.setWidget(0, 0, Ikitchen);
				flexTable_1.setWidget(0, 1, Ilivingroom);
				flexTable_1.setWidget(1, 0, Ibathroom);
				flexTable_1.setWidget(1, 1, Ibedroom);
				flexTable_1.setWidget(0, 2, Ioutside);
				lblWelcome.setText("Welcome to home page, click on Cuisine button for demonstration");
				History.newItem("home");



			}
		});

		pshbtnRetour.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				//Window.Location.assign(GWT.getHostPageBaseURL()+"#home"); 
				String url = Window.Location.getHref();
				String search = "#";
				int index = url.indexOf(search);
				if(index > -1) {
					String result = url.substring(0, index + search.length());
					result = result+Tokens.get(Tokens.size()-2);

					Window.Location.assign(result);
					Window.Location.reload();
				}

			}
		}); 

		btnInformation.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ChooseRequestLocation(Tokens,"Informations"); //A mettre en premier parmi toutes les requêtes onClick
				History.newItem("Informations");

			}
		}); 
		btnSecurite.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ChooseRequestLocation(Tokens,"Securite");
				History.newItem("Securite");
			}
		}); 
		btnTemperature.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ChooseRequestLocation(Tokens,"Temperature");
				History.newItem("Temperature");
			}
		}); 

		btnMultimedia.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ChooseRequestLocation(Tokens,"Multimedia");
				History.newItem("Multimedia");
			}
		}); 



		//System.out.println(Tokens);

		flexTable_1.setWidget(0, 0, Ikitchen);
		flexTable_1.setWidget(0, 1, Ilivingroom);
		flexTable_1.setWidget(1, 0, Ibathroom);
		flexTable_1.setWidget(1, 1, Ibedroom);
		flexTable_1.setWidget(0, 2, Ioutside);
		flexTable_1.getCellFormatter().setVerticalAlignment(0, 2, HasVerticalAlignment.ALIGN_MIDDLE);


		FlexTable flexTable = new FlexTable();
		tabPanel.add(flexTable, "Par types", false);


		// Return the content
		tabPanel.selectTab(0);
		tabPanel.ensureDebugId("cwTabPanel");


		rootPanel.add(tabPanel, 0, 0);
		Integer height = Window.getClientHeight();
		Integer width = Window.getClientWidth();
		tabPanel.setSize("716px", "493px");
		//   rootPanel.setPixelSize(width, height);


		rootPanel.add(btnAccueil, 615, 516);
		btnAccueil.setSize("64px", "37px");
		rootPanel.add(Panel, -219, 353);
		rootPanel.add(lblWelcome, 10, 516);
		lblWelcome.setSize("297px", "45px");
		lblWelcome.setText("Welcome to home page, click on Cuisine button for demonstration");
		pshbtnRetour.setHTML("Retour");
		rootPanel.add(pshbtnRetour, 494, 516);
		pshbtnRetour.setSize("64px", "37px");

		btnAmpoule.setSize("150px", "150px");
		btnSecurite.setSize("150px", "150px");
		btnMultimedia.setSize("150px", "150px");
		btnInformation.setSize("150px", "150px");
		btnTemperature.setSize("150px", "150px");






		History.addValueChangeHandler(this);
		if(History.getToken().isEmpty()) {
			History.newItem("home");
		} else {
			changePage(History.getToken());
		}



	}

	public void onHistoryChanged(String historyToken)
	{
		//  oldToken = historyToken;
		//  System.out.println("L'ancienne clÃ© est "+ oldToken);
	} 


	public void onValueChange(ValueChangeEvent event) {
		System.out.println("L'ancienne clÃ© (avant) "+ Tokens);
		oldToken = (String) event.getValue();
		System.out.println("ClÃ© courante : " + oldToken);
		Tokens.add(oldToken);
		System.out.println("L'ancienne clÃ© (aprÃ¨s) "+ Tokens);
		changePage(History.getToken());
	}




	public void changePage(String token) {
		if(History.getToken().equals("retour")) {
			lblWelcome.setText("Vous avez appuye sur le bouton retour");
		}
		else if(History.getToken().equals("home")) {
			Tokens.add("home");
		}
		else if(History.getToken().equals("Kitchen")) {
			Tokens.add("home");
			Tokens.add("Kitchen");
			flexTable_1.clear();
			Panel.clear();
			lblWelcome.setText("Nous sommes dans la cuisine");
			flexTable_1.setWidget(0,1,btnAmpoule);
			flexTable_1.setWidget(0,2,btnSecurite);
			flexTable_1.setWidget(0,3,btnMultimedia);
			flexTable_1.setWidget(1,1,btnTemperature);
			flexTable_1.setWidget(1,2,btnInformation);
		}
		else if(History.getToken().equals("Salon")) {
			Tokens.add("home");
			Tokens.add("Salon");
			flexTable_1.clear();
			Panel.clear();
			lblWelcome.setText("Nous sommes dans le salon");
			flexTable_1.setWidget(0,1,btnAmpoule);
			flexTable_1.setWidget(0,2,btnSecurite);
			flexTable_1.setWidget(0,3,btnMultimedia);
			flexTable_1.setWidget(1,1,btnTemperature);
			flexTable_1.setWidget(1,2,btnInformation);
		}
		else if(History.getToken().equals("Bedroom")) {
			Tokens.add("home");
			Tokens.add("Bedroom");
			flexTable_1.clear();
			Panel.clear();
			lblWelcome.setText("Nous sommes dans la chambre");
			flexTable_1.setWidget(0,1,btnAmpoule);
			flexTable_1.setWidget(0,2,btnSecurite);
			flexTable_1.setWidget(0,3,btnMultimedia);
			flexTable_1.setWidget(1,1,btnTemperature);
			flexTable_1.setWidget(1,2,btnInformation);
		}
		else if(History.getToken().equals("Bathroom")) {
			Tokens.add("home");
			Tokens.add("Bathroom");
			flexTable_1.clear();
			Panel.clear();
			lblWelcome.setText("Nous sommes dans la salle de bain");
			flexTable_1.setWidget(0,1,btnAmpoule);
			flexTable_1.setWidget(0,2,btnSecurite);
			flexTable_1.setWidget(0,3,btnMultimedia);
			flexTable_1.setWidget(1,1,btnTemperature);
			flexTable_1.setWidget(1,2,btnInformation);
		}

		else if(History.getToken().equals("Outside")) {
			Tokens.add("home");
			Tokens.add("Outside");
			flexTable_1.clear();
			Panel.clear();
			lblWelcome.setText("Nous sommes sur la terrasse");
			flexTable_1.setWidget(0,1,btnAmpoule);
			flexTable_1.setWidget(0,2,btnSecurite);
			flexTable_1.setWidget(0,3,btnMultimedia);
			flexTable_1.setWidget(1,1,btnTemperature);
			flexTable_1.setWidget(1,2,btnInformation);
		}

		else {

		}

	}


	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
		+ "attempting to contact the server. Please check your network "
		+ "connection and try again.";

	/**
	 * Create a remote service proxy to talk to the server-side Greeting service.
	 */
	private final GreetingServiceAsync greetingService = GWT
	.create(GreetingService.class);






	/**
	 * Convert the string of JSON into JavaScript object.
	 */
	private final native JsArray<EquipmentData> asArrayOfEquipmentData(String json) /*-{
	      return eval(json);
	    }-*/;

	/**
	 * If can't get JSON, display error message.
	 * @param error
	 */

	private void displayError(String error) {
		errorMsgLabel.setText("Error: " + error);
		errorMsgLabel.setVisible(true);
	}

	private void diplayInfos(JsArray<EquipmentData> equipments) {
		listDevices=equipments;
		for (int i = 0; i < equipments.length(); i++) {
			displayInfo(equipments.get(i));
		}

		// Clear any errors.
		errorMsgLabel.setVisible(false);

	}

	private void displayButtons(final JsArray<EquipmentData> listDevices, JsArray<EquipmentData> listState, int i) {

		if (listDevices.get(i).getName().equals("Light")) {
			Label label = new Label();
			State=listState.get(0).getState();
			System.out.println("Status :" + State);
			ToggleButton sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.eteinte()),new Image(ImageResource.INSTANCE.allumee()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());

			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			if(State.equals("1")){
				sendButton.setDown(true);
			}



			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});


		}
		else if (listDevices.get(i).getName().equals("GazMeter")) {
			ToggleButton sendButton;
			Label label = new Label();
			sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.gazmeter()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());
			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});

		}
		else if (listDevices.get(i).getName().equals("EnergyMeter")) {
			ToggleButton sendButton;
			Label label = new Label();
			sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.energymeter()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());
			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});

		}
		else if (listDevices.get(i).getName().equals("WaterMeter")) {
			ToggleButton sendButton;
			Label label = new Label();
			sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.watermeter()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());
			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});

		}
		else if (listDevices.get(i).getName().equals("Alarm")) {
			ToggleButton sendButton;
			Label label = new Label();
			sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.alarm()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());
			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			System.out.println("Ok alarm");
			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});

		}
		else if (listDevices.get(i).getName().equals("Heater")) {
			ToggleButton sendButton;
			Label label = new Label();
			sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.heater()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());
			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});

		}

		else if (listDevices.get(i).getName().equals("LightSensor")) {
			ToggleButton sendButton;
			Label label = new Label();
			sendButton = new ToggleButton(new Image(ImageResource.INSTANCE.lightsensor()));
			sendButton.setSize("80px", "80px");
			label.setText(listDevices.get(i).getId());
			flexTable_1.setWidget(i,0,sendButton);	
			flexTable_1.setWidget(i,1,label);	
			sendButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {

				}
			});

		}
	}

	private void displayInfo(EquipmentData equipment) {
		System.out.println("Id: "+equipment.getId());
		System.out.println("Location: "+equipment.getLocation());
		System.out.println("Type: "+equipment.getType());
		System.out.println("Name: "+equipment.getName());

		// Clear any errors.
		errorMsgLabel.setVisible(false);

	}

	private void ChooseRequestLocation(ArrayList<String> Tokens, String type) {
		RequestsOnServer(Tokens.get(Tokens.size()-1),type);
		System.out.println("Location:" + Tokens.get(Tokens.size()-1));
	}

	private void RequestsOnServer(String location, String type) {

		String url = JSON_URL+"getDevices&location="+location+"&type="+type;
		url = URL.encode(url);
		System.out.println(url);
		Window.alert(url);
		// Send request to server and catch any errors.
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
		try {
			Request request = builder.sendRequest(null, new RequestCallback() {
				@Override
				public void onError(Request request, Throwable exception) {
					displayError("Couldn't retrieve JSON");
				}

				@Override
				public void onResponseReceived(Request request, Response response) {
					if (200 == response.getStatusCode()) {
						//diplayInfos(asArrayOfEquipmentData(response.getText()));
						flexTable_1.clear();
						listDevices=asArrayOfEquipmentData(response.getText());
						for(int i=0;i<listDevices.length();i++) {
							RequestOnState(listDevices,i);
						}

					} else {
						displayError("Couldn't retrieve JSON (" + response.getStatusText()
								+ ")");
					}
				}
			});
		} catch (RequestException e) {
			displayError("Couldn't retrieve JSON");
		}

	}

	private void RequestOnState(final JsArray<EquipmentData> listDevices2, final int i) {


		String url = JSON_URL+"getState&id="+listDevices2.get(i).getId()+"&location="+listDevices2.get(i).getLocation()+"&type="+listDevices2.get(i).getType();
		url = URL.encode(url);
		System.out.println(url);
		Window.alert(url);
		// Send request to server and catch any errors.
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);

		try {
			Request request = builder.sendRequest(null, new RequestCallback() {
				@Override
				public void onError(Request request, Throwable exception) {
					displayError("Couldn't retrieve JSON");
				}

				public void onResponseReceived(Request request, Response response) {
					if (200 == response.getStatusCode()) {
						//diplayInfos(asArrayOfEquipmentData(response.getText()));
						listState=asArrayOfEquipmentData(response.getText());
						System.out.println("Status OnResponse :" + listState.get(0).getState());
						displayButtons(listDevices2,listState, i);



					} else {
						displayError("Couldn't retrieve JSON (" + response.getStatusText() + ")");
					}
				}

			});


		} catch (RequestException e) {
			displayError("Couldn't retrieve JSON");
		}


	}


}